package service

import (
	"errors"
	"gitee.com/sansaniot/ssiot-core/httpmvc/service"
	"ssdevice/common/constant"
	cDto "ssdevice/common/dto"
	"ssdevice/common/utils"
	"ssdevice/internal/device/models"
	"ssdevice/internal/device/models/command"
	"ssdevice/internal/device/models/query"
	"strings"
	"time"
)

type DeviceTask struct {
	sysOTAPackage *models.SysOTAPackage
	sysBatchTask  *models.SysBatchTask
	sysTaskDevice *models.SysTaskDevice
	service.Service
}

func (d *DeviceTask) SetOTAPackageModel(m *models.SysOTAPackage) *DeviceTask {
	d.sysOTAPackage = m
	return d
}

func (d *DeviceTask) SetBatchTaskModel(m *models.SysBatchTask) *DeviceTask {
	d.sysBatchTask = m
	return d
}

func (d *DeviceTask) SetTaskDeviceModel(m *models.SysTaskDevice) *DeviceTask {
	d.sysTaskDevice = m
	return d
}

func (d *DeviceTask) SetAllModel() {
	d.sysOTAPackage = &models.SysOTAPackage{}
	d.sysBatchTask = &models.SysBatchTask{}
	d.sysTaskDevice = &models.SysTaskDevice{}
	d.sysOTAPackage.Orm = d.Orm
	d.sysBatchTask.Orm = d.Orm
	d.sysTaskDevice.Orm = d.Orm
}

// 添加安装包
func (d *DeviceTask) AddPackage(req *command.PackageInsertReq) (err error, otaPackage models.SysOTAPackage) {
	if err = req.Generate(&otaPackage); err != nil {
		return
	}

	if err = d.sysOTAPackage.Add(otaPackage); err != nil {
		return
	}
	return
}

// 编辑安装包
func (d *DeviceTask) ModPackage(req *command.PackageUpdateReq) (err error, otaPackage models.SysOTAPackage) {
	if err = req.Generate(&otaPackage); err != nil {
		return
	}

	if err = d.sysOTAPackage.Mod(otaPackage); err != nil {
		return
	}
	return
}

// 删除安装包
func (d *DeviceTask) DelPackage(req *command.PackageDeleteReq) (err error) {
	delIds := strings.Split(strings.ReplaceAll(req.Id, " ", ""), ",")
	if err = d.sysOTAPackage.Delete(&models.SysOTAPackage{}, cDto.MakeCondition(query.SysOTAPackageQuery{IdIn: delIds})); err != nil {
		return err
	}
	return
}

// 添加任务
func (d *DeviceTask) AddBatchTask(req *command.BatchTaskInsertReq) (err error, batchTask models.SysBatchTask) {
	if err = req.Generate(&batchTask); err != nil {
		return
	}

	if err = d.sysBatchTask.Add(batchTask); err != nil {
		return
	}

	return
}

// 编辑任务
func (d *DeviceTask) ModBatchTask(req *command.BatchTaskUpdateReq) (err error, batchTask models.SysBatchTask) {
	if err = req.Generate(&batchTask); err != nil {
		return
	}

	if err = d.sysBatchTask.Mod(batchTask); err != nil {
		return
	}
	return
}

// 删除任务
func (d *DeviceTask) DelBatchTask(req *command.BatchTaskDeleteReq) (err error) {
	delIds := strings.Split(strings.ReplaceAll(req.Id, " ", ""), ",")
	if err = d.sysBatchTask.Delete(&models.SysBatchTask{}, cDto.MakeCondition(query.SysBatchTaskQuery{IdIn: delIds})); err != nil {
		return err
	}
	return
}

// 新增：获取任务关联设备
func (d *DeviceTask) getTaskDevices(task models.SysBatchTask) ([]models.SysDev, error) {
	dev := &models.SysDev{}
	dev.Orm = d.Orm
	devList := make([]models.SysDev, 0)

	queryReq := query.SysDevQuery{ProductModel: task.ProductId, GatewaySn: ""}
	filters := utils.BytesToMap(task.Filters)

	if filters["sns"] != nil {
		queryReq.SnIn = strings.Split(strings.ReplaceAll(filters["sns"].(string), " ", ""), ",")
	} else {
		if filters["deptId"] != nil {
			queryReq.DeptId = filters["deptId"].(string)
		} else {
			if filters["version"] != nil {
				//TODO 按版本过滤升级设备
			}
		}
	}

	if err := dev.FindList(&devList, cDto.MakeCondition(queryReq)); err != nil {
		return nil, err
	}

	return devList, nil
}

// 新增：创建子任务记录
func (d *DeviceTask) createChildTaskRecords(task models.SysBatchTask, devList []models.SysDev) error {
	// 删除旧子任务
	if err := d.sysTaskDevice.Delete(&models.SysTaskDevice{}, cDto.MakeCondition(query.SysTaskDeviceQuery{TaskId: task.Id})); err != nil {
		return err
	}

	// 批量创建新子任务
	childTasks := make([]models.SysTaskDevice, 0, len(devList))
	now := cDto.LocalTime(time.Now())

	for _, v := range devList {
		childTask := models.SysTaskDevice{
			TaskId:       task.Id,
			DevSn:        v.Sn,
			Status:       constant.DeviceTaskPending,
			Id:           utils.SimpleUUID(),
			CreateTime:   &now,
			UpdateTime:   &now,
			PlanExecTime: &now,
			Sid:          int64(utils.AtomicAddSid()),
		}

		childTasks = append(childTasks, childTask)
	}

	// 批量插入
	sliceList := chunkSlice(childTasks, 1000)
	for _, v := range sliceList {
		if count := d.sysTaskDevice.Orm.Create(v).RowsAffected; count == 0 {
			return errors.New("create device task error")
		}
	}
	return nil
}

func (d *DeviceTask) ExecBatchTask(req *command.BatchTaskExecReq) (err error) {
	exeTaskIds := strings.Split(strings.ReplaceAll(req.Id, " ", ""), ",")

	for _, v := range exeTaskIds {
		var one models.SysBatchTask
		oneReq := query.SysBatchTaskQuery{}
		oneReq.Id = v

		err = d.sysTaskDevice.FindOne(&one, cDto.MakeCondition(oneReq.GetNeedSearch()))
		if err != nil {
			continue
		}

		if one.Status == constant.BatchTaskRunning {
			return errors.New("task is in progress, please try later")
		}
		// 更新状态
		one.Status = constant.BatchTaskRunning
		err = d.sysTaskDevice.Mod(one)
		if err != nil {
			return err
		}

		// 创建子任务设备列表
		devList, err := d.getTaskDevices(one)
		if err != nil {
			return err
		}

		if err = d.createChildTaskRecords(one, devList); err != nil {
			return err
		}
	}

	return
}
